iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
AI & Data

看圖說故事,讓 Neo4j 重新詮釋你的資料庫系列 第 16

Neo4j 資料庫查詢效能優化 - 執行計畫

  • 分享至 

  • xImage
  •  

在上一篇文章中,介紹了在 Neo4j 建立索引和約束,來增加查詢效率或確保資料的完整、一致性,那麼說到效率,我們怎麼知道查詢的效率好壞呢?今天要介紹的是如何讓 Neo4j 查詢最佳化,以及提升效率還有哪些作法。

EXPLAIN 檢視查詢計畫

在 Cypher 語法前面加上 EXPLAIN,就可以檢視查詢計畫,但 EXPLAIN 後面的敘述不會真的被執行。相對的,所能得到的計畫資訊只是一部分。

EXPLAIN MATCH (c) WHERE c.companyName = 'Wartian Herkku'
RETURN c

Neo4j Cypher Explain

PROFILE 檢視查詢計畫

在 Cypher 語法前面加上 PROFILE,就可以更細節的檢視查詢計畫,除了 EXPLAIN 的所有資訊外,還可額外得知記憶體用量與 db hits 等資訊。
PROFILE 後面的 Cypher 敘述會真的執行,比 EXPLAIN 佔用更多系統資源,在非常大量的資料庫做初步的效能分析時,建議先採用 EXPLAIN 尋找問題,然後再斟酌使用 PROFILE。

PROFILE MATCH (c) WHERE c.companyName = 'Wartian Herkku'
RETURN c

Neo4j Cypher Profile

Cypher version: CYPHER 4.1, planner: COST, runtime: PIPELINED. 13747 total db hits

從執行結果看到,上述的查詢共發生了 13747 次 db hits,這是 Neo4j 資料庫的抽象存取單位,另外我刻意忽略了後面還有花了多少時間執行,因為那只是參考,通常第一次都跑比較久,第二次的執行時間會大幅降低。

上面兩張圖,都表示著 Cypher 的執行計畫(Execution Plan),而圖中每個階段就是一個運算子(Operator),而每個運算子都會接收來自上一個運算子的結果,執行運算後再將資料送到下一個運算子,直到取得最後查詢結果。

以上圖為例,執行的步驟如下:

  1. AllNodesScan
    掃描所有節點,北風資料庫中所有節點數就是 1036,所以全部的節點都會送往下一個運算子
  2. Filter
    這裏會先找到全部有 companyName 屬性的節點,104 estimated rows 只是估計值,是 Neo4j 的靜態統計資料,用來協助 Neo4j 評估最佳的執行計畫。
    而 12710 db hits,就是在全部 1036 個節點上尋找 companyName 屬性的花費,Filter 結束後找到 1 筆
  3. ProduceResults
    輸出最後的結果

查詢效能優化 Part 1

對查詢計畫有概念後,接著我們可以開始逐步優化它

第一個問題便是:我們明明知道 companyName 就是 Customer 的欄位;或是反過來說,我們就是要查詢客戶資料,那為何不限制只查詢 Customer 呢?
就好比關聯式資料庫,我們幾乎不會一次查詢所有的資料表。

把上述語法改進如下:

PROFILE MATCH (c:Customer) WHERE c.companyName = 'Wartian Herkku'
RETURN c

Neo4j Cypher Profile with Label

Cypher version: CYPHER 4.1, planner: COST, runtime: PIPELINED. 387 total db hits

從原本 12710 db hits 大幅縮小到 387 db hits !!!
接著看執行計畫也出現新的運算子

NodeByLabelScan

這是掃瞄 Customer 所有節點,全部的 Customer 節點就是 91 個。後面的運算子與步驟就都類似了。

而在實務的應用上,如果 companyName 被查詢的頻率很高,可考慮加上索引。我們來看看加上索引後的執行狀況

CREATE INDEX ON :Customer(companyName)

Neo4j Cypher Profile with Label Index

Cypher version: CYPHER 4.1, planner: COST, runtime: PIPELINED. 2 total db hits

這次竟然只花費了兩次 db hits !!!

並且用了 NodeIndexSeek 運算子,也就是有用到索引來提升效率。

關於執行計畫與運算子,可以參考官網有更詳細的資訊 https://neo4j.com/docs/cypher-manual/current/execution-plans
下次再為大家介紹更進階的查詢優化方式


上一篇
Neo4j 資料庫索引與約束
下一篇
Neo4j 資料庫查詢效能優化 - 起始點
系列文
看圖說故事,讓 Neo4j 重新詮釋你的資料庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言